C++17前，要使用类模板的对象，必须显式指定模板参数。

\begin{tcolorbox}[colback=webgreen!5!white,colframe=webgreen!75!black]
\hspace*{0.75cm}C++17引入了类参数模板推导，若模板参数可以从构造函数派生，则可以跳过这些参数。这会在第2.9节中进行讨论。
\end{tcolorbox}

下面的例子展示了如何使用类模板Stack<>:

\hspace*{\fill} \\ %插入空行
\noindent
\textit{basics/stack1test.cpp}
\begin{lstlisting}[style=styleCXX]
#include "stack1.hpp"
#include <iostream>
#include <string>

int main()
{
	Stack<int> intStack; // stack of ints
	Stack<std::string> stringStack; // stack of strings
	
	// manipulate int stack
	intStack.push(7);
	std::cout << intStack.top() << '\n';
	
	// manipulate string stack
	stringStack.push("hello");
	std::cout << stringStack.top() << '\n';
	stringStack.pop();
}
\end{lstlisting}

通过声明类型Stack<int>，int在类模板中作为类型T。因此，intStack是一个对象，使用的是vector<int>类型，并且调用相应的成员函数。类似地，通过声明和使用Stack<std::string>，将创建使用vector<std::string>的对象，使用相应的成员函数。

注意，代码只对调用的模板(成员)函数实例化。对于类模板，只有在使用成员函数时才实例化。当然，这节省了时间和空间，并且只允许使用部分地类模板，这会在2.3节中详细讨论。

例子中，默认构造函数push()和top()为int和string实例化，但pop()只对string实例化。如果类模板具有静态成员，则对于使用类模板的每个类型实例，这些成员也会实例化一次。

可以像使用其他类型一样使用实例化的类模板类型。可以使用const、volatile或从中派生数组和引用类型对其进行限定。也可以将其作为类型定义的一部分，使用typedef或using(请参阅第2.8节了解关于类型定义的详细信息)，或者在构建另一个模板类型时将其用作类型参数。例如:

\begin{lstlisting}[style=styleCXX]
void foo(Stack<int> const& s) // parameter s is int stack
{
	using IntStack = Stack<int>; // IntStack is another name for Stack<int>
	Stack<int> istack[10]; // istack is array of 10 int stacks
	IntStack istack2[10]; // istack2 is also an array of 10 int stacks (same type)
	...
}
\end{lstlisting}

模板参数可以是任何类型，例如float指针，甚至是Stack<int>:

\begin{lstlisting}[style=styleCXX]
Stack<float*> floatPtrStack; // stack of float pointers
Stack<Stack<int>> intStackStack; // stack of stack of ints
\end{lstlisting}

这里的要求是，需要这种类型支持所使用的操作。

注意，在C++11之前，必须在两个模板右括号之间放空格:

\begin{lstlisting}[style=styleCXX]
Stack<Stack<int> > intStackStack; // 所有C++版本都可以用
\end{lstlisting}

如果没有这样做，就使用>{}>，会导致语法错误:

\begin{lstlisting}[style=styleCXX]
Stack<Stack<int>> intStackStack; // C++11之前会报错
\end{lstlisting}

旧行为可以帮助C++编译器对独立于代码语义源码进行标记。然而，由于缺少空格是一个错误，这需要相应的错误消息，因此无论如何都必须考虑代码的语义。因此，在C++11中，在两个模板右括号之间放一个空格的规则被“尖括号黑客”删除了(详见13.3.1节)。





















